/**
 * @Name:  Reduce
 * @Author:
 * @Desc:  Reduce方法使用
 * @Date: 2020-11-19 14:22:56
 */

import React, { Component } from "react";
import { Title, HighLightJs } from "@/component";

import styles from "./styles.module.less";
// 参考：https://www.jianshu.com/p/e375ba1cfc47
//       https://segmentfault.com/n/1330000016503710

const highOne = `let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
  if(cur in pre){
    pre[cur]++
  }else{
    pre[cur] = 1 
  }
  return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}`;
const highTwo = `let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
    if(pre.indexOf(cur) === -1){
      return pre.concat(cur)
    }else{
      return pre
    }
},[])
console.log(newArr);// [1, 2, 3, 4]`;
const highThree = `let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
    return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]`;
const highFour = `let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
   return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]`;
const highFive = `let names = [
  { name: ["Alice"], code: "101" },
  { name: ["Bob"], code: "102" },
  { name: ["Alice"], code: "101" },
  { name: ["Tiff"], code: "101" },
  { name: ["Bruce"], code: "105" }
];
const arrMerge = names.reduce((pre, curr) => {
  const eqIndex = pre.findIndex((item) => item.code === curr.code);
  if (eqIndex !== -1) {
    pre[eqIndex].name.push(...curr.name);
    return pre;
  } else {
    return pre.concat(curr);
  }
}, []);
console.log(arrMerge); 
//[{code:'101',name:['Alice','Alice','Tiff']}, {code:'102',name:['Bob']}, {code:'105',name:['Bruce']}]`;

const highSix = `let arr = [
  { name: "ming", grade: 87 },
  { name: "hong", grade: 84 },
  { name: "jun", grade: 91 },
  { name: "jun", grade: 87 }
];
let newArr = arr.reduce((pre, cur) => {
  //cur参数是否在pre数据中，有则>-1
  let eqIndex = pre.findIndex((item) => item.name === cur.name);
  if (eqIndex > -1) {
    pre[eqIndex].grade += cur.grade;
    return pre;
  } else {
    pre.push(cur);
    return pre;
  }
}, []);
console.log("newarr==", newArr);
// [
//   { name: "ming", grade: 87 },
//   { name: "hong", grade: 84 },
//   { name: "jun", grade: 178 }
// ];`;
class Reduce extends Component {
  sum = () => {
    let arr = [1, 2, 3, 4];
    let sum = arr.reduce((prev, cur) => prev + cur); //10
    return sum;
  };
  mul = () => {
    let arr = [1, 2, 3, 4];
    let mul = arr.reduce((prev, cur) => prev * cur); //24
    return mul;
  };
  test = () => {
    let str = "008,00801,008,00802,009,00901";
    let arr = str.split(",");
    let num = 4;
    let newArr = arr.reduce((pre, cur, index) => {
      if (index % num === 0) {
        return pre.concat([arr.slice(index, index + num)]);
      } else {
        return pre;
      }
    }, []);
    console.log("newarr==", newArr); //[["008","00801"],["008","00802"],["009","00901"]]
  };
  test1 = () => {
    let arr = [
      { name: "ming", grade: 87 },
      { name: "hong", grade: 84 },
      { name: "jun", grade: 91 },
      { name: "jun", grade: 87 }
    ];
    let newArr = arr.reduce((pre, cur) => {
      //cur参数是否在pre数据中，有则>-1
      let eqIndex = pre.findIndex((item) => item.name === cur.name);
      if (eqIndex === -1) {
        pre.push(cur);
        return pre;
      } else {
        return pre;
      }
    }, []);
    console.log("newarr==", newArr);
    // [
    //   { name: "ming", grade: 87 },
    //   { name: "hong", grade: 84 },
    //   { name: "jun", grade: 178 }
    // ];
  };
  render() {
    return (
      <div>
        <p>reduce方法使用</p>
        <p>
          reduce()环境要求 <codes>Google：Yes；IE：9.0↑； Firefox：3.0↑； opera：10.5↑</codes>
        </p>
        <div className={styles.block}>
          <Title text="理解" />
          <codearea>
            <p>
              <codes>reduce</codes>是对数组进行操作，
            </p>
            <p>
              标准格式：<codes>{`let newArr = arr.reduce((pre,cur)=>{xxx},{})`}</codes>
            </p>
            <p>其中newArr为预期结果；</p>
            <p>arr为目标数组；</p>
            <p>xxx为逻辑函数；</p>
            <p>
              原理： pre，在初始时为原型<codes>{"{}"}</codes>，也是代码最末尾那个<codes>{"{}"}</codes>
              标识，之后变为代码xxx中返回的结果，继续对arr中下一个元素进行操作；
            </p>
          </codearea>
        </div>
        {this.test()}
        <div className={styles.block}>
          <Title text="简单用法" />
          <div>
            <div>arr:[1,2,3,4] </div>
            求和：{"arr.reduce((prev,cur)=>prev+cur)"}
            <div>结果：{this.sum()}</div>
            <p />
            乘积：{"arr.reduce((prev,cur)=>prev*cur)"}
            <div>结果：{this.mul()}</div>
          </div>
        </div>
        <div className={styles.block}>
          <Title text="高阶用法" />
          <div>
            <h3>01：统计字符串出现次数</h3>
            <HighLightJs type="javascript" data={highOne} />
          </div>
          <div>
            <h3>02：数组去重</h3>
            <HighLightJs type="javascript" data={highTwo} />
          </div>
          <div>
            <h3>03：二维数组转一维</h3>
            <HighLightJs type="javascript" data={highThree} />
          </div>
          <div>
            <h3>04：多维数组转一维</h3>
            <HighLightJs type="javascript" data={highFour} />
          </div>
          <div>
            <h3>05：数组相同项合并</h3>
            <HighLightJs type="javascript" data={highFive} />
          </div>
          <div>
            {this.test1()}
            <h3>06：数组对象相同项求和</h3>
            <HighLightJs type="javascript" data={highSix} />
          </div>
        </div>
      </div>
    );
  }
}

export default Reduce;
